/*     */ package com.zimbra.cs.service.account;
/*     */ 
/*     */ import com.zimbra.common.account.Key.AccountBy;
/*     */ import com.zimbra.common.account.Key.DomainBy;
/*     */ import com.zimbra.common.account.ZAttrProvisioning.AutoProvAuthMech;
/*     */ import com.zimbra.common.service.ServiceException;
/*     */ import com.zimbra.common.soap.AccountConstants;
/*     */ import com.zimbra.common.soap.Element;
/*     */ import com.zimbra.common.soap.Element.Disposition;
/*     */ import com.zimbra.common.util.Log;
/*     */ import com.zimbra.common.util.ZimbraCookie;
/*     */ import com.zimbra.common.util.ZimbraLog;
/*     */ import com.zimbra.cs.account.Account;
/*     */ import com.zimbra.cs.account.AccountServiceException.AuthFailedServiceException;
/*     */ import com.zimbra.cs.account.AttributeFlag;
/*     */ import com.zimbra.cs.account.AttributeManager;
/*     */ import com.zimbra.cs.account.AuthToken;
/*     */ import com.zimbra.cs.account.AuthTokenException;
/*     */ import com.zimbra.cs.account.Domain;
/*     */ import com.zimbra.cs.account.Provisioning;
/*     */ import com.zimbra.cs.account.Server;
/*     */ import com.zimbra.cs.account.auth.AuthContext.Protocol;
/*     */ import com.zimbra.cs.account.krb5.Krb5Principal;
/*     */ import com.zimbra.cs.account.names.NameUtil.EmailAddress;
/*     */ import com.zimbra.cs.service.AuthProvider;
/*     */ import com.zimbra.cs.servlet.util.CsrfUtil;
/*     */ import com.zimbra.cs.session.Session;
/*     */ import com.zimbra.cs.util.AccountUtil;
/*     */ import com.zimbra.cs.util.SkinUtil;
/*     */ import com.zimbra.soap.ZimbraSoapContext;
/*     */ import java.util.HashMap;
/*     */ import java.util.Iterator;
/*     */ import java.util.Map;
/*     */ import java.util.Set;
/*     */ import javax.servlet.ServletRequest;
/*     */ import javax.servlet.http.HttpServletRequest;
/*     */ import javax.servlet.http.HttpServletResponse;
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ public class Auth
/*     */   extends AccountDocumentHandler
/*     */ {
/*     */   public Element handle(Element request, Map<String, Object> context)
/*     */     throws ServiceException
/*     */   {
/*  73 */     ZimbraSoapContext zsc = getZimbraSoapContext(context);
/*  74 */     Provisioning prov = Provisioning.getInstance();
/*     */     
/*     */ 
/*  77 */     String acctValuePassedIn = null;String acctValue = null;String acctByStr = null;
/*  78 */     Key.AccountBy acctBy = null;
/*  79 */     Account acct = null;
/*  80 */     Element acctEl = request.getOptionalElement("account");
/*  81 */     boolean csrfSupport = request.getAttributeBool("csrfTokenSecured", false);
/*     */     
/*  83 */     if (acctEl != null) {
/*  84 */       acctValuePassedIn = acctEl.getText();
/*  85 */       acctValue = acctValuePassedIn;
/*  86 */       acctByStr = acctEl.getAttribute("by", Key.AccountBy.name.name());
/*  87 */       acctBy = Key.AccountBy.fromString(acctByStr);
/*  88 */       if (acctBy == Key.AccountBy.name) {
/*  89 */         Element virtualHostEl = request.getOptionalElement("virtualHost");
/*  90 */         String virtualHost = virtualHostEl == null ? null : virtualHostEl.getText().toLowerCase();
/*  91 */         if ((virtualHost != null) && (acctValue.indexOf('@') == -1)) {
/*  92 */           Domain d = prov.get(Key.DomainBy.virtualHostname, virtualHost);
/*  93 */           if (d != null)
/*  94 */             acctValue = acctValue + "@" + d.getName();
/*     */         }
/*     */       }
/*  97 */       acct = prov.get(acctBy, acctValue);
/*     */     }
/*     */     
/* 100 */     Element authTokenEl = request.getOptionalElement("authToken");
/* 101 */     if (authTokenEl != null) {
/* 102 */       boolean verifyAccount = authTokenEl.getAttributeBool("verifyAccount", false);
/* 103 */       if ((verifyAccount) && (acctEl == null)) {
/* 104 */         throw ServiceException.INVALID_REQUEST("missing required element: account", null);
/*     */       }
/*     */       try {
/* 107 */         AuthToken at = AuthProvider.getAuthToken(authTokenEl, acct);
/*     */         
/* 109 */         addAccountToLogContextByAuthToken(prov, at);
/*     */         
/*     */ 
/*     */ 
/*     */ 
/* 114 */         if (!checkPasswordSecurity(context)) {
/* 115 */           throw ServiceException.INVALID_REQUEST("clear text password is not allowed", null);
/*     */         }
/* 117 */         Account authTokenAcct = AuthProvider.validateAuthToken(prov, at, false);
/* 118 */         if (verifyAccount)
/*     */         {
/*     */ 
/*     */ 
/* 122 */           if ((acct == null) || (!acct.getId().equalsIgnoreCase(authTokenAcct.getId()))) {
/* 123 */             throw new AuthTokenException("auth token doesn't match the named account");
/*     */           }
/*     */         }
/* 126 */         ServletRequest httpReq = (ServletRequest)context.get("servlet.request");
/* 127 */         httpReq.setAttribute("AuthToken", at);
/* 128 */         if ((csrfSupport) && (!at.isCsrfTokenEnabled()))
/*     */         {
/*     */ 
/*     */ 
/* 132 */           at.setCsrfTokenEnabled(csrfSupport);
/*     */         }
/*     */         
/* 135 */         return doResponse(request, at, zsc, context, authTokenAcct, csrfSupport);
/*     */       } catch (AuthTokenException e) {
/* 137 */         throw ServiceException.AUTH_REQUIRED();
/*     */       }
/*     */     }
/* 140 */     if (!checkPasswordSecurity(context)) {
/* 141 */       throw ServiceException.INVALID_REQUEST("clear text password is not allowed", null);
/*     */     }
/*     */     
/* 144 */     Element preAuthEl = request.getOptionalElement("preauth");
/* 145 */     String password = request.getAttribute("password", null);
/*     */     
/* 147 */     long expires = 0L;
/*     */     
/* 149 */     Map<String, Object> authCtxt = new HashMap();
/* 150 */     authCtxt.put("ocip", context.get("orig.request.ip"));
/* 151 */     authCtxt.put("remoteip", context.get("soap.request.ip"));
/* 152 */     authCtxt.put("anp", acctValuePassedIn);
/* 153 */     authCtxt.put("ua", zsc.getUserAgent());
/*     */     
/* 155 */     boolean acctAutoProvisioned = false;
/* 156 */     if (acct == null)
/*     */     {
/*     */ 
/*     */ 
/* 160 */       if ((acctBy == Key.AccountBy.name) || (acctBy == Key.AccountBy.krb5Principal)) {
/*     */         try {
/* 162 */           if (acctBy == Key.AccountBy.name) {
/* 163 */             NameUtil.EmailAddress email = new NameUtil.EmailAddress(acctValue, false);
/* 164 */             String domainName = email.getDomain();
/* 165 */             Domain domain = domainName == null ? null : prov.get(Key.DomainBy.name, domainName);
/* 166 */             if (password != null) {
/* 167 */               acct = prov.autoProvAccountLazy(domain, acctValuePassedIn, password, null);
/* 168 */             } else if (preAuthEl != null) {
/* 169 */               long timestamp = preAuthEl.getAttributeLong("timestamp");
/* 170 */               expires = preAuthEl.getAttributeLong("expires", 0L);
/* 171 */               String preAuth = preAuthEl.getTextTrim();
/* 172 */               prov.preAuthAccount(domain, acctValue, acctByStr, timestamp, expires, preAuth, authCtxt);
/*     */               
/* 174 */               acct = prov.autoProvAccountLazy(domain, acctValuePassedIn, null, ZAttrProvisioning.AutoProvAuthMech.PREAUTH);
/*     */             }
/* 176 */           } else if ((acctBy == Key.AccountBy.krb5Principal) && 
/* 177 */             (password != null)) {
/* 178 */             Domain domain = Krb5Principal.getDomainByKrb5Principal(acctValuePassedIn);
/* 179 */             if (domain != null) {
/* 180 */               acct = prov.autoProvAccountLazy(domain, acctValuePassedIn, password, null);
/*     */             }
/*     */           }
/*     */           
/*     */ 
/* 185 */           if (acct != null) {
/* 186 */             acctAutoProvisioned = true;
/*     */           }
/*     */         } catch (AccountServiceException.AuthFailedServiceException e) {
/* 189 */           ZimbraLog.account.debug("auth failed, unable to auto provisioing acct " + acctValue, e);
/*     */         } catch (ServiceException e) {
/* 191 */           ZimbraLog.account.info("unable to auto provisioing acct " + acctValue, e);
/*     */         }
/*     */       }
/*     */     }
/*     */     
/* 196 */     if (acct == null) {
/* 197 */       throw AccountServiceException.AuthFailedServiceException.AUTH_FAILED(acctValue, acctValuePassedIn, "account not found");
/*     */     }
/*     */     
/* 200 */     AccountUtil.addAccountToLogContext(prov, acct.getId(), "name", "id", null);
/*     */     
/*     */ 
/* 203 */     if (!acctAutoProvisioned) {
/* 204 */       if (password != null) {
/* 205 */         prov.authAccount(acct, password, AuthContext.Protocol.soap, authCtxt);
/* 206 */       } else if (preAuthEl != null) {
/* 207 */         long timestamp = preAuthEl.getAttributeLong("timestamp");
/* 208 */         expires = preAuthEl.getAttributeLong("expires", 0L);
/* 209 */         String preAuth = preAuthEl.getTextTrim();
/* 210 */         prov.preAuthAccount(acct, acctValue, acctByStr, timestamp, expires, preAuth, authCtxt);
/*     */       } else {
/* 212 */         throw ServiceException.INVALID_REQUEST("must specify password", null);
/*     */       }
/*     */     }
/*     */     
/* 216 */     AuthToken at = expires == 0L ? AuthProvider.getAuthToken(acct) : AuthProvider.getAuthToken(acct, expires);
/* 217 */     ServletRequest httpReq = (ServletRequest)context.get("servlet.request");
/*     */     
/* 219 */     if ((csrfSupport) && (!at.isCsrfTokenEnabled()))
/*     */     {
/*     */ 
/*     */ 
/* 223 */       at.setCsrfTokenEnabled(csrfSupport);
/*     */     }
/* 225 */     httpReq.setAttribute("AuthToken", at);
/* 226 */     return doResponse(request, at, zsc, context, acct, csrfSupport);
/*     */   }
/*     */   
/*     */ 
/*     */   private Element doResponse(Element request, AuthToken at, ZimbraSoapContext zsc, Map<String, Object> context, Account acct, boolean csrfSupport)
/*     */     throws ServiceException
/*     */   {
/* 233 */     Element response = zsc.createElement(AccountConstants.AUTH_RESPONSE);
/* 234 */     at.encodeAuthResp(response, false);
/*     */     
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/* 240 */     HttpServletRequest httpReq = (HttpServletRequest)context.get("servlet.request");
/* 241 */     HttpServletResponse httpResp = (HttpServletResponse)context.get("servlet.response");
/* 242 */     boolean rememberMe = request.getAttributeBool("persistAuthTokenCookie", false);
/* 243 */     at.encode(httpResp, false, ZimbraCookie.secureCookie(httpReq), rememberMe);
/*     */     
/* 245 */     response.addAttribute("lifetime", at.getExpires() - System.currentTimeMillis(), Element.Disposition.CONTENT);
/* 246 */     boolean isCorrectHost = Provisioning.onLocalServer(acct);
/* 247 */     if (isCorrectHost) {
/* 248 */       Session session = updateAuthenticatedAccount(zsc, at, context, true);
/* 249 */       if (session != null) {
/* 250 */         ZimbraSoapContext.encodeSession(response, session.getSessionId(), session.getSessionType());
/*     */       }
/*     */     }
/* 253 */     Server localhost = Provisioning.getInstance().getLocalServer();
/* 254 */     String referMode = localhost.getAttr("zimbraMailReferMode", "wronghost");
/*     */     
/* 256 */     if (("always".equals(referMode)) || (("wronghost".equals(referMode)) && (!isCorrectHost)))
/*     */     {
/* 258 */       response.addAttribute("refer", acct.getAttr("zimbraMailHost"), Element.Disposition.CONTENT);
/*     */     }
/*     */     
/* 261 */     Element prefsRequest = request.getOptionalElement("prefs");
/* 262 */     if (prefsRequest != null) {
/* 263 */       Element prefsResponse = response.addUniqueElement("prefs");
/* 264 */       GetPrefs.handle(prefsRequest, prefsResponse, acct);
/*     */     }
/*     */     
/* 267 */     Element attrsRequest = request.getOptionalElement("attrs");
/* 268 */     Element attrsResponse; Set<String> attrList; Iterator it; if (attrsRequest != null) {
/* 269 */       attrsResponse = response.addUniqueElement("attrs");
/* 270 */       attrList = AttributeManager.getInstance().getAttrsWithFlag(AttributeFlag.accountInfo);
/* 271 */       for (it = attrsRequest.elementIterator("attr"); it.hasNext();) {
/* 272 */         Element e = (Element)it.next();
/* 273 */         String name = e.getAttribute("name");
/* 274 */         if ((name != null) && (attrList.contains(name))) {
/* 275 */           Object v = acct.getUnicodeMultiAttr(name);
/* 276 */           if (v != null) {
/* 277 */             ToXML.encodeAttr(attrsResponse, name, v);
/*     */           }
/*     */         }
/*     */       }
/*     */     }
/*     */     
/* 283 */     Element requestedSkinEl = request.getOptionalElement("requestedSkin");
/* 284 */     String requestedSkin = requestedSkinEl != null ? requestedSkinEl.getText() : null;
/* 285 */     String skin = SkinUtil.chooseSkin(acct, requestedSkin);
/* 286 */     ZimbraLog.webclient.debug("chooseSkin() returned " + skin);
/* 287 */     if (skin != null) {
/* 288 */       response.addElement("skin").setText(skin);
/*     */     }
/*     */     
/* 291 */     boolean csrfCheckEnabled = false;
/* 292 */     if (httpReq.getAttribute("zimbraCsrfTokenCheckEnabled") != null) {
/* 293 */       csrfCheckEnabled = ((Boolean)httpReq.getAttribute("zimbraCsrfTokenCheckEnabled")).booleanValue();
/*     */     }
/*     */     
/* 296 */     if ((csrfSupport) && (csrfCheckEnabled)) {
/* 297 */       String accountId = at.getAccountId();
/* 298 */       long authTokenExpiration = at.getExpires();
/* 299 */       int tokenSalt = ((Integer)httpReq.getAttribute("CSRF_SALT")).intValue();
/* 300 */       String token = CsrfUtil.generateCsrfToken(accountId, authTokenExpiration, tokenSalt, at);
/*     */       
/* 302 */       Element csrfResponse = response.addUniqueElement("csrfToken");
/* 303 */       csrfResponse.addText(token);
/* 304 */       httpResp.setHeader("X-Zimbra-Csrf-Token", token);
/*     */     }
/*     */     
/* 307 */     return response;
/*     */   }
/*     */   
/*     */   public boolean needsAuth(Map<String, Object> context)
/*     */   {
/* 312 */     return false;
/*     */   }
/*     */   
/*     */   public static void addAccountToLogContextByAuthToken(Provisioning prov, AuthToken at)
/*     */   {
/* 317 */     String id = at.getAccountId();
/* 318 */     if (id != null)
/* 319 */       AccountUtil.addAccountToLogContext(prov, id, "name", "id", null);
/* 320 */     String aid = at.getAdminAccountId();
/* 321 */     if ((aid != null) && (!aid.equals(id))) {
/* 322 */       AccountUtil.addAccountToLogContext(prov, aid, "aname", "aid", null);
/*     */     }
/*     */   }
/*     */ }


/* Location:              /home/mint/zimbrastore.jar!/com/zimbra/cs/service/account/Auth.class
 * Java compiler version: 7 (51.0)
 * JD-Core Version:       0.7.1
 */